home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <grx.h>
- #include <mousex.h>
- #include <io.h>
-
- typedef unsigned char uchar;
- typedef unsigned short ushort;
-
- typedef struct {
- uchar maker;
- uchar version;
- uchar code;
- uchar bpp; /* bits per pixel */
- ushort x1,y1,x2,y2; /* image position */
- ushort hres,vres; /* image size */
- struct { uchar R,G,B; } cmap[16]; /* palette */
- uchar vmode; /* video mode to display it */
- uchar nplanes; /* number of planes */
- ushort bpl; /* bytes per scan line */
- char filler[128 - 68];
- } pcxhdr;
-
- #if defined(__GNUC__) && defined(__MSDOS__)
- #define MAX_COLORS 32768 /* maximum color graphics mode supported */
- #else
- #define MAX_COLORS 256 /* maximum color graphics mode supported */
- #endif
- #define MAX_OUTCOLORS 16 /* max number of simultaneous colors */
- #define MAX_WIDTH 1280 /* max horizontal image size */
-
- static int dumpCount = 0;
-
- int pcxdump(char *fname)
- {
- GrContext save,xfer;
- pcxhdr hdr;
- uchar rows[4][MAX_WIDTH / 8];
- char colortable[MAX_COLORS];
- char pcxfname[100];
- FILE *pcxfile;
- int numcolors,block,fast;
- int ii,xx,yy,wdt,hgt;
-
- if(GrCurrentMode() < GR_320_200_graphics) return(0);
- if(GrNumColors() > MAX_COLORS) return(0);
- wdt = GrScreenX();
- hgt = GrScreenY();
- if(wdt > MAX_WIDTH) return(0);
- if(fname == NULL) for( ; ; ) {
- /* find a new file name */
- sprintf(pcxfname,"dump%04d.pcx",dumpCount);
- if(access(pcxfname,0) != 0) {
- pcxfile = fopen(pcxfname,"wb");
- if(pcxfile == NULL) return(0);
- break;
- }
- if(++dumpCount >= 10000) return(0);
- }
- else {
- strcpy(pcxfname,fname);
- pcxfile = fopen(pcxfname,"wb");
- if(pcxfile == NULL) return(0);
- }
- GrSaveContext(&save);
- GrCreateContext(wdt,1,NULL,&xfer);
- GrSetContext(&xfer);
- memset(&hdr,0,sizeof(pcxhdr));
- memset(colortable,-1,sizeof(colortable));
- hdr.maker = 10;
- hdr.version = 5;
- hdr.code = 1;
- hdr.x1 = 0;
- hdr.y1 = 0;
- hdr.x2 = wdt - 1;
- hdr.y2 = hgt - 1;
- hdr.hres = wdt;
- hdr.vres = hgt;
- hdr.bpp = 1;
- hdr.bpl = (wdt + 7) / 8;
- hdr.vmode = 0x12; /* standard 640x480 16 color VGA ! */
- hdr.nplanes = 4;
- numcolors = 0;
- fast = (GrNumColors() == 256) ? 1 : 0;
- block = MouseCursorIsDisplayed();
- if(block) MouseEraseCursor();
- fwrite(&hdr,sizeof(pcxhdr),1,pcxfile);
- for(yy = 0; yy < hgt; yy++) {
- uchar mask = 0x80;
- int bytepos = 0;
- int numbits = 0;
- GrBitBlt(&xfer,0,0,&save,0,yy,wdt-1,yy,GrWRITE);
- memset(rows,0,sizeof(rows));
- for(xx = 0; xx < wdt; xx++) {
- int color = fast ? xfer.gc_baseaddr[xx] : GrPixel(xx,0);
- char outcolor = colortable[color];
- if(outcolor < 0) { /* new color */
- int r,g,b;
- GrQueryColor(color,&r,&g,&b);
- for(ii = 0; ii < numcolors; ii++) {
- if(hdr.cmap[ii].R != r) continue;
- if(hdr.cmap[ii].G != g) continue;
- if(hdr.cmap[ii].B != b) continue;
- outcolor = ii;
- break;
- }
- if(outcolor < 0) {
- if(numcolors >= MAX_OUTCOLORS) goto error;
- outcolor = ii = numcolors++;
- hdr.cmap[ii].R = r;
- hdr.cmap[ii].G = g;
- hdr.cmap[ii].B = b;
- }
- colortable[color] = outcolor;
- }
- if(outcolor & 1) rows[0][bytepos] |= mask;
- if(outcolor & 2) rows[1][bytepos] |= mask;
- if(outcolor & 4) rows[2][bytepos] |= mask;
- if(outcolor & 8) rows[3][bytepos] |= mask;
- mask >>= 1;
- if(++numbits == 8) {
- mask = 0x80;
- numbits = 0;
- bytepos++;
- }
- }
- for(ii = 0; ii < 4; ii++) {
- uchar *ptr = rows[ii];
- uchar pixval = *ptr;
- numbits = 0;
- for(bytepos = hdr.bpl; --bytepos >= 0; ptr++) {
- if(pixval != *ptr) {
- while(numbits > 0x3f) {
- putc((0xc0 | 0x3f),pcxfile);
- putc(pixval,pcxfile);
- numbits -= 0x3f;
- }
- if(numbits > 0) {
- if((numbits > 1) || (pixval >= 0xc0))
- putc((0xc0 | numbits),pcxfile);
- putc(pixval,pcxfile);
- }
- numbits = 0;
- }
- pixval = *ptr;
- numbits++;
- }
- while(numbits > 0x3f) {
- putc((0xc0 | 0x3f),pcxfile);
- putc(pixval,pcxfile);
- numbits -= 0x3f;
- }
- if(numbits > 0) {
- if((numbits > 1) || (pixval >= 0xc0))
- putc((0xc0 | numbits),pcxfile);
- putc(pixval,pcxfile);
- }
- }
- }
- if(ferror(pcxfile)) goto error;
- if(block) MouseDisplayCursor();
- GrSetContext(&save);
- GrDestroyContext(&xfer);
- fseek(pcxfile,0L,0);
- fwrite(&hdr,sizeof(pcxhdr),1,pcxfile);
- fclose(pcxfile);
- return(1);
- error:
- if(block) MouseDisplayCursor();
- GrSetContext(&save);
- GrDestroyContext(&xfer);
- fclose(pcxfile);
- unlink(pcxfname);
- return(0);
- }
-
-